﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

using Weazel.Badger.Vhdl.Types;

namespace Weazel.Badger.Vhdl.Expressions
{
  public class SignalReferenceExpression : Expression
  {
    private Signal signal;
    public Signal Signal
    {
      get
      {
        return signal;
      }

      set
      {
        signal = value;
      }
    }

		public SignalReferenceExpression(IComponent parentContainer, Signal signal)
			: base(parentContainer, signal.Type, signal.GezelType)
    {
      this.signal = signal;
    }

		public SignalReferenceExpression(IComponent parentContainer, Signal signal, Gezel.Model.Expression expr)
			: base(parentContainer, signal.Type, signal.GezelType, expr)
    {
      this.signal = signal;
    }

    public override string ToString()
    {
      return signal.ToString();
    }

    private TypeSet s;

    public override TypeSet GetPossibleTypes()
    {
      // has same type as underlying signal
      s = signal.GetPossibleTypes();
      return s; 
    }

		public override void SetActualType(Entity entity, Process process, Statements.StatementCollection statements, Vhdl.Types.Type type) //, int width)
    {
      if (!signal.GetPossibleTypes().Contains(type))
      {
        string message =
          string.Format(
            "Actual type must be the same as type of port or signal '{0}'. " + 
            "Vhdl type: {1}, Supported vhdl type(s): {2}.",

            signal.Name,
            type,
            signal.GetPossibleTypes()
          );

        throw new TypeResolveException(message);
      }

      this.Type = type;
      // ActualType = type;
     // Width = width;
			signal.SetActualType(entity, process, statements, type);
    }

    public override bool VerifyType(ref List<VerifyMessage> messages)
    {
      if (this.Type == Types.Types.Undefined)
      {
        messages.Add(new VerifyMessage(string.Format("no type set for signal reference expression refering signal '{0}'", signal.Name)));
        return false;
      }

      return true;
    }
  }
}
